GeneralUpdate 入门实战手册
这篇手册面向第一次接触 GeneralUpdate 的开发者。目标不是一次讲完所有 API,而是让你从零开始,写完 Client → 写完 Upgrade → 用 Tools 生成配置 → 启动 Server → 一条命令跑通完整的"发现更新 → 下载 → 应用 → 回到新版本"闭环。
完成这篇手册后,你会拥有一个可运行的端到端自动更新系统:一个能检查更新的 Client、一个能应用更新的 Upgrade、一份自动生成的 manifest、以及一个本地测试 Server。
更新流程总览
┌──────────────────────────────────────────────────────────────────────┐
│ GeneralUpdate 完整更新流程 │
└──────────────────────────────────────────────────────────────────────┘
① 版本检查 ② 下载包 ③ 应用更新
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Client │──POST──→ │ Server │ │ Upgrade │
│ (主程序) │←─JSON─── │ (更新服务)│ │ (升级进程) │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
│ POST /Upgrade/Verification │ │
│ {version, platform} │ │
│ ────────────────────→│ │
│ │ │
│ [{version, url, │ │
│ hash, size}] │ │
│ ←────────────────────│ │
│ │ │
│ GET /File/Download │ │
│ ────────────────────→│ │
│ │ │
│ .zip packages │ │
│ ←────────────────────│ │
│ │ │
│ [写入 IPC 加密契约] │ │
│ [启动 Upgrade.exe] │ │
│ ────────────────────────────────────────────→│
│ │ │
│ │ [读取 IPC 数据] │
│ │ [校验 Hash] │
│ │ [解压 → 覆盖] │
│ │ [启动新版本 Client] │
│ │ │
│ ←────────────────────────────────────────────│
│ [新版本运行中 ✓] │ │
│ │ │
| 角色 | 在项目中的位置 | 负责什么 |
|---|---|---|
| Client | MyApp.exe(你自己的主程序) | 检查更新 → 下载包 → 启动 Upgrade |
| Upgrade | MyApp.Upgrade.exe(独立的升级进程) | 校验 Hash → 解压覆盖 → 启动新版 Client |
| Server | GeneralUpdate-Samples/src/Server | 返回版本信息、接收更新报告、提供补丁下载 |
| Tools | GeneralUpdate.Tools | 生成 generalupdate.manifest.json,串联 Client 与 Upgrade |
Phase 1:环境准备
安装清单
| 项 | 要求 | 验证命令 |
|---|---|---|
| .NET SDK | 8.0+(推荐 10.0) | dotnet --version |
| Git | 任意版本 | git --version |
新建项目
打开终端,创建 Client 和 Upgrade 两个控制台项目:
dotnet new console -n MyApp
dotnet new console -n MyApp.Upgrade
cd MyApp
dotnet add package GeneralUpdate.Core
cd ../MyApp.Upgrade
dotnet add package GeneralUpdate.Core
预期结果:两个项目目录下都有 GeneralUpdate.Core 的 NuGet 引用。
Phase 2:集成 Client 代码
在
MyApp/Program.cs中粘贴以下全部内容。Client 负责:检查更新 → 下载包 → 启动 Upgrade。
using GeneralUpdate.Core;
using GeneralUpdate.Core.Configuration;
using GeneralUpdate.Core.Event;
// ================================================================
// Client — 主程序入口,负责检测和下载更新
// ================================================================
// 只需设置 3 个 secret。MainAppName、ClientVersion、UpdateAppName
// 等身份字段由框架自动从 generalupdate.manifest.json 发现,无需手写。
var request = new UpdateRequest
{
UpdateUrl = "http://localhost:5000/Upgrade/Verification",
ReportUrl = "http://localhost:5000/Upgrade/Report",
AppSecretKey = "dfeb5833-975e-4afb-88f1-6278ee9aeff6",
};
await new GeneralUpdateBootstrap()
.SetConfig(request)
.SetOption(Option.AppType, AppType.Client)
.AddListenerUpdateInfo((_, e) =>
{
Console.WriteLine($"发现 {e.Info?.Body?.Count ?? 0} 个可用更新");
if (e.Info?.Body != null)
{
foreach (var v in e.Info.Body)
Console.WriteLine($" v{v.Version} — {v.Name} ({v.Size} bytes)");
}
})
.AddListenerMultiDownloadStatistics((_, e) =>
{
Console.WriteLine($"\r下载: {e.ProgressPercentage:F0}% {e.Speed}");
})
.AddListenerMultiDownloadCompleted((_, e) =>
{
Console.WriteLine();
Console.WriteLine($"下载 {(e.IsCompleted ? "✓ 完成" : "✗ 失败")}");
})
.AddListenerException((_, e) =>
{
Console.WriteLine($"异常: {e.Exception.Message}");
})
.LaunchAsync();
为什么只设 3 个参数?
ClientStrategy 在执行时会自动调用 AppMetadataDiscoverer.Discover(),从 generalupdate.manifest.json(Phase 4 用 Tools 生成)中读取身份字段并补全 UpdateRequest:
| 字段 | 谁负责 | 说明 |
|---|---|---|
UpdateUrl | 你写代码 | Server 验证接口地址 |
ReportUrl | 你写代码 | Server 报告接口地址 |
AppSecretKey | 你写代码 | 应用密钥 |
MainAppName | 框架自动发现 | 从 manifest 读取 |
ClientVersion | 框架自动发现 | 从 manifest 读取 |
UpdateAppName | 框架自动发现 | 从 manifest 读取 |
ProductId | 框架自动发现 | 从 manifest 读取 |
UpdatePath | 框架自动发现 | 从 manifest 读取 |
InstallPath | 默认值 | AppDomain.CurrentDomain.BaseDirectory |
如果你不想写 UpdateRequest,还可以用更简短的 SetSource():
await new GeneralUpdateBootstrap()
.SetSource("http://localhost:5000/Upgrade/Verification",
"dfeb5833-975e-4afb-88f1-6278ee9aeff6",
"http://localhost:5000/Upgrade/Report")
.SetOption(Option.AppType, AppType.Client)
// ... listeners
.LaunchAsync();
Client 不直接应用更新——下载完成后写 IPC 加密契约 → 启动 Upgrade → 自身退出。
Client 只负责发现和下载,文件替换工作完全交给独立的 Upgrade 进程。这是因为运行中的进程无法覆盖自身的可执行文件——通过 IPC 加密契约把控制权交给 Upgrade,是实现"自己更新自己"的核心架构。
Phase 3:集成 Upgrade 代码
在
MyApp.Upgrade/Program.cs中粘贴以下全部内容。Upgrade 比 Client 更简单——不需要SetConfig(),所有参数通过加密 IPC 文件从 Client 传入。
using GeneralUpdate.Core;
using GeneralUpdate.Core.Configuration;
using GeneralUpdate.Core.Event;
// ================================================================
// Upgrade — 独立的 升级进程 (MyApp.Upgrade.exe)
// 无需 SetConfig(),参数由 Client 通过加密 IPC 文件传入
// ================================================================
await new GeneralUpdateBootstrap()
.SetOption(Option.AppType, AppType.Upgrade)
.AddListenerMultiDownloadStatistics((_, e) =>
{
Console.WriteLine($"\r应用补丁: {e.ProgressPercentage:F0}%");
})
.AddListenerMultiDownloadCompleted((_, e) =>
{
Console.WriteLine();
Console.WriteLine($"补丁 {(e.IsCompleted ? "✓ 完成" : "✗ 失败")}");
})
.AddListenerException((_, e) =>
{
Console.WriteLine($"异常: {e.Exception.Message}");
})
.LaunchAsync();
Client vs Upgrade 差异
| Client | Upgrade | |
|---|---|---|
AppType | AppType.Client | AppType.Upgrade |
SetConfig() | ✅ 必须,设置服务器地址 、版本等 | ❌ 不需要,通过 IPC 从 Client 获取 |
| 职责 | 检查版本 → 下载包 → 启动 Upgrade | Hash 校验 → 解压覆盖 → 启动新版 Client |
| 谁启动谁 | 由用户直接启动 | 由 Client 进程自动启动 |
Phase 4:使用 Tools 生成项目结构
Client 和 Upgrade 代码写好后,用 Tools 的配置生成器(Config 标签页)一键
dotnet publish并生成generalupdate.manifest.json。
操作步骤
打开 GeneralUpdate.Tools → 切换到 Config 标签页(配置生成器):
- Client .csproj Path:点击 Browse,选择
MyApp.csproj - Upgrade .csproj Path:点击 Browse,选择
MyApp.Upgrade.csproj - 点击 Analyze:Tools 解析两个 .csproj,自动填入:
MainAppName:来自 Client 项目的 AssemblyName(如MyApp.exe)UpdateAppName:来自 Upgrade 项目的 AssemblyName(如MyApp.Upgrade.exe)ClientVersion/UpgradeClientVersion:默认1.0.0,按需修改
- 检查自动填入的字段,确认
UpdatePath为update/(默认值) - 点击 Generate Sample